package ldkxingzhe.l365calendar.fragment.presenter;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.UUID;

import ldkxingzhe.l365calendar.App;
import ldkxingzhe.l365calendar.R;
import ldkxingzhe.l365calendar.fragment.ScheduleAlarmFragment;
import ldkxingzhe.l365calendar.fragment.ScheduleFragment;
import ldkxingzhe.l365calendar.model.TimeStore;
import ldkxingzhe.l365calendar.utils.CalendarUtil;
import ldkxingzhe.l365calendar.utils.OSUtil;
import ldkxingzhe.l365calendar.widget.dialog.ListAlertDialogFragment;
import ldkxingzhe.l365calendar.widget.dialog.picker.DatePicker;

/**
 * 日程界面的Presenter
 * Created by ke on 16-1-28.
 */
public class SchedulePresenter {
    @SuppressWarnings("unused")
    private static final String TAG = "SchedulePresenter";

    // 完全状态的开始时间和终止时间 2016-01-29 13-44-00
    private long startTime = 0, endTime = 0;
    private boolean isSetEndTime = false;

    private String[] alarmAllDayNames, alarmTimeNames;

    private ArrayList<Long> alarmBeforeTime = new ArrayList<>();

    public void setStartTime(long startTime){
        this.startTime = startTime;
    }

    public void setEndTime(long endTime){
        this.endTime = endTime;
    }

    public void onStartTimeClick() {
        startTime = makeSureTimeNice(startTime);
        mView.showTimePicker(endTime, 0);
    }

    private long makeSureTimeNice(long time){
        return time > 0 ? time : new Date().getTime();
    }

    public void onEndTimeClick() {
        endTime = makeSureTimeNice(endTime);
        mView.showTimePicker(endTime, 1);
    }

    public void onIsWholeDayChanged(boolean isChecked) {
        String format = getFormat();
        mView.setStartTimeText(CalendarUtil.formatTime(startTime, format));
        if(isSetEndTime){
            mView.setEndTimeText(CalendarUtil.formatTime(endTime, format));
        }
        calculateAlarmBefore(isChecked);
        showAlarmTime();
    }

    void calculateAlarmBefore(boolean isChecked) {
        Iterator<Long> iterator = alarmBeforeTime.iterator();
        while (iterator.hasNext()){
            if(TimeStore.indexOf(iterator.next(), isChecked) == -1){
                iterator.remove();
                continue;
            }
        }
        if(alarmBeforeTime.size() == 0){
            alarmBeforeTime.add((long) -1);
        }
    }

    public void onHandleTimePickerResult(int requestCode, int resultCode, Intent data) {
        if(resultCode == Activity.RESULT_CANCELED) return;
        String resultStr = data.getStringExtra(DatePicker.RESULT);
        long resultTimeLong = 0;
        try {
            resultTimeLong = CalendarUtil.parseTime(resultStr, getFormat()).getTime();
        } catch (Exception e) {
            Log.e(TAG, e.getMessage(), e);
            return; // throw?
        }
        switch (requestCode){
            case 0:
                onStartTimeResult(resultStr, resultTimeLong);
                break;
            case 1:
                onEndTimeResult(resultStr, resultTimeLong);
                break;
            default:
                Log.e(TAG, "onHandleFragment, and requestCode is " + requestCode);
        }
    }

    private void onEndTimeResult(String resultStr, long resultTimeLong) {
        if(resultTimeLong < getStartTimeLong()){
            mView.showAlert(R.string.start_time_before_end_time);
            return;
        }
        mView.setEndTimeText(resultStr);
        endTime = resultTimeLong;
        isSetEndTime = true;
    }

    private void onStartTimeResult(String resultStr, long resultTimeLong) {
        if(isSetEndTime){
            if(resultTimeLong > getEndTimeLong()){
                mView.showAlert(R.string.start_time_before_end_time);
                return;
            }
        }

        mView.setStartTimeText(resultStr);
        startTime = resultTimeLong;
    }

    public long getStartTimeLong(){
        return parseTime(mView.getStartTimeText());
    }

    private long parseTime(String time) {
        try {
            return CalendarUtil.parseTime(time, getFormat()).getTime();
        } catch (ParseException e) {
            Log.e(TAG, e.getMessage(), e);
        }
        return 0;
    }

    private long getEndTimeLong(){
        return  parseTime(mView.getEndTimeText());
    }

    private String getFormat(){
        return mView.getIsWholeDaySchedule() ? CalendarUtil.DATE : CalendarUtil.TIME_HM;
    }

    public void onHandleListAlertResult(int resultCode, Intent data) {
        if(resultCode == Activity.RESULT_CANCELED) return;
        int position = data.getIntExtra(ListAlertDialogFragment.RESULT, -1);
        switch (position){
            case 0:
                break;
            case 1:
                preparePickPhoto();
                break;
            case -1:
                Log.e(TAG, "position is default value, and some wrong");
                break;
            default:
                Log.e(TAG, "position is wrong, and position is " + position);
        }
    }

    private String lastPickImagePath = null;
    //拾取照片
    private void preparePickPhoto() {
        Intent photoPickIntent = new Intent(Intent.ACTION_GET_CONTENT);
        lastPickImagePath = OSUtil.getApplicationFilePath("picture",
                UUID.randomUUID().toString(),
                Bitmap.CompressFormat.JPEG.name());
        photoPickIntent.setType("image/*");
        photoPickIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.encode(lastPickImagePath));
        photoPickIntent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
        photoPickIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.name());
        photoPickIntent.putExtra("return-data", true);
        mView.startActivityForResult(photoPickIntent, ScheduleFragment.REQUEST_PICK_PHOTO);
    }

    public void onPickPhotoResult(int resultCode, Intent data){
        Log.v(TAG, "onPickPhotoResult");
        if(lastPickImagePath == null){
            Log.e(TAG, "lastPickImagePath is null");
            return;
        }
        File file = new File(lastPickImagePath);
        if(!file.exists()){
//            file.mkdirs();
            Uri resultUri = data.getData();
            try {
                InputStream in = App.applicationContext.getContentResolver().openInputStream(resultUri);
                OutputStream out = new FileOutputStream(file);
                byte[] bytes = new byte[1024];
                int len;
                while((len = in.read(bytes)) > 0){
                    out.write(bytes, 0, len);
                }
                in.close();   // java 1.6 ?
                out.close();
            } catch (Exception e) {
                Log.e(TAG, e.getMessage(), e);
            }
        }
    }

    public void onAlarmResult(int resultCode, Intent data) {
        alarmBeforeTime.clear();
        ArrayList<Integer> alarmResult = data.getIntegerArrayListExtra(ScheduleAlarmFragment.RESULT);
        for(Integer index : alarmResult){
            alarmBeforeTime.add(getAlarmBeforeTime(index));
        }
        showAlarmTime();
    }

    private void showAlarmTime(){
        mView.alarmDetailLayoutClear();
        if(alarmBeforeTime.size() == 1){
            mView.setAlarmDetailLayoutVisibility(View.GONE);
            long tmpTime = alarmBeforeTime.get(0);
            String value;
            if(tmpTime == -1){
                value = null;
            }else{
                value = CalendarUtil.formatTime(getStartTimeLong() - tmpTime, CalendarUtil.TIME_HM);
            }
            mView.alarmLayoutNameValue(getAlarmName(TimeStore.indexOf(tmpTime, mView.getIsWholeDaySchedule())),
                    value);
        }else{
            mView.setAlarmDetailLayoutVisibility(View.VISIBLE);
            mView.alarmLayoutNameValue("提醒次数", alarmBeforeTime.size() + "次");
            for(long tmpTime : alarmBeforeTime){
                mView.alarmDetailLayoutAddView(getAlarmName(TimeStore.indexOf(tmpTime, mView.getIsWholeDaySchedule())),
                        CalendarUtil.formatTime(getStartTimeLong() - tmpTime, CalendarUtil.TIME_HM));
            }
        }
    }

    private int getAlarmTypeCount(){
        if(mView.getIsWholeDaySchedule()){
            return TimeStore.allDayTime.length;
        }else{
            return TimeStore.alarmTime.length;
        }
    }

    String getAlarmName(int index){
        if(mView.getIsWholeDaySchedule()){
            if(alarmAllDayNames == null){
                alarmAllDayNames = App.applicationContext.getResources()
                        .getStringArray(R.array.all_day_times);
            }
            return alarmAllDayNames[index];
        }else{
            if(alarmTimeNames == null){
                alarmTimeNames = App.applicationContext.getResources()
                        .getStringArray(R.array.alarms_times);
            }
            return alarmTimeNames[index];
        }
    }

    long getAlarmBeforeTime(int index){
        if(mView.getIsWholeDaySchedule()){
            return TimeStore.allDayTime[index];
        }else{
            return TimeStore.alarmTime[index];
        }
    }

    public interface PView{
        void setIsChanged(boolean isChanged);
        boolean getIsWholeDaySchedule();
        String getStartTimeText();
        String getEndTimeText();
        String getCategoryText();
        String getDescriptionText();
        void setStartTimeText(String startTimeText);
        void setEndTimeText(String endTimeText);
        void showTimePicker(long timeLong, int request);
        void showAlert(int stringId);
        void startActivityForResult(Intent intent, int requestCode);
        void setAlarmDetailLayoutVisibility(int visibility);
        void alarmLayoutNameValue(String leftName, String rightValue);
        void alarmDetailLayoutClear();
        void alarmDetailLayoutAddView(String name, String value);
    }
    private PView mView;
    public void setView(PView view){
        this.mView = view;
    }
}
